home *** CD-ROM | disk | FTP | other *** search
/ Aminet 44 / Aminet 44 (2001)(GTI - Schatztruhe)[!][Aug 2001].iso / Aminet / dev / misc / AmigaSDLsrc.lha / amisrc / SDL_blit.h < prev    next >
C/C++ Source or Header  |  2001-04-29  |  12KB  |  438 lines

  1. /*
  2.     SDL - Simple DirectMedia Layer
  3.     Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
  4.  
  5.     This library is free software; you can redistribute it and/or
  6.     modify it under the terms of the GNU Library General Public
  7.     License as published by the Free Software Foundation; either
  8.     version 2 of the License, or (at your option) any later version.
  9.  
  10.     This library is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.     Library General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU Library General Public
  16.     License along with this library; if not, write to the Free
  17.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  
  19.     Sam Lantinga
  20.     slouken@devolution.com
  21. */
  22.  
  23. #ifdef SAVE_RCSID
  24. static char rcsid =
  25.  "@(#) $Id: SDL_blit.h,v 1.3.2.15 2001/02/13 10:05:50 hercules Exp $";
  26. #endif
  27.  
  28. #ifndef _SDL_blit_h
  29. #define _SDL_blit_h
  30.  
  31. #include "SDL_endian.h"
  32.  
  33. /* The structure passed to the low level blit functions */
  34. typedef struct {
  35.     Uint8 *s_pixels;
  36.     int s_width;
  37.     int s_height;
  38.     int s_skip;
  39.     Uint8 *d_pixels;
  40.     int d_width;
  41.     int d_height;
  42.     int d_skip;
  43.     void *aux_data;
  44.     SDL_PixelFormat *src;
  45.     Uint8 *table;
  46.     SDL_PixelFormat *dst;
  47. } SDL_BlitInfo;
  48.  
  49. /* The type definition for the low level blit functions */
  50. typedef void (*SDL_loblit)(SDL_BlitInfo *info);
  51.  
  52. /* This is the private info structure for software accelerated blits */
  53. struct private_swaccel {
  54.     SDL_loblit blit;
  55.     void *aux_data;
  56. };
  57.  
  58. /* Blit mapping definition */
  59. typedef struct SDL_BlitMap {
  60.     SDL_Surface *dst;
  61.     int identity;
  62.     Uint8 *table;
  63.     SDL_blit hw_blit;
  64.     SDL_blit sw_blit;
  65.     struct private_hwaccel *hw_data;
  66.     struct private_swaccel *sw_data;
  67.  
  68.     /* the version count matches the destination; mismatch indicates
  69.        an invalid mapping */
  70.         unsigned int format_version;
  71. } SDL_BlitMap;
  72.  
  73.  
  74. /* Definitions for special global blit functions */
  75. #include "SDL_blit_A.h"
  76.  
  77. /* Functions found in SDL_blit.c */
  78. extern int SDL_CalculateBlit(SDL_Surface *surface);
  79.  
  80. /* Functions found in SDL_blit_{0,1,N,A}.c */
  81. extern SDL_loblit SDL_CalculateBlit0(SDL_Surface *surface, int complex);
  82. extern SDL_loblit SDL_CalculateBlit1(SDL_Surface *surface, int complex);
  83. extern SDL_loblit SDL_CalculateBlitN(SDL_Surface *surface, int complex);
  84. extern SDL_loblit SDL_CalculateAlphaBlit(SDL_Surface *surface, int complex);
  85.  
  86. /*
  87.  * Useful macros for blitting routines
  88.  */
  89.  
  90. #define FORMAT_EQUAL(A, B)                        \
  91.     ((A)->BitsPerPixel == (B)->BitsPerPixel                \
  92.      && ((A)->Rmask == (B)->Rmask) && ((A)->Amask == (B)->Amask))
  93.  
  94. /* Load pixel of the specified format from a buffer and get its R-G-B values */
  95. /* FIXME: rescale values to 0..255 here? */
  96. #define RGB_FROM_PIXEL(pixel, fmt, r, g, b)                \
  97. {                                    \
  98.     r = (((pixel&fmt->Rmask)>>fmt->Rshift)<<fmt->Rloss);         \
  99.     g = (((pixel&fmt->Gmask)>>fmt->Gshift)<<fmt->Gloss);         \
  100.     b = (((pixel&fmt->Bmask)>>fmt->Bshift)<<fmt->Bloss);         \
  101. }
  102. #define RGB_FROM_RGB565(pixel, r, g, b)                    \
  103. {                                    \
  104.     r = (((pixel&0xF800)>>11)<<3);                     \
  105.     g = (((pixel&0x07E0)>>5)<<2);                     \
  106.     b = ((pixel&0x001F)<<3);                     \
  107. }
  108. #define RGB_FROM_RGB555(pixel, r, g, b)                    \
  109. {                                    \
  110.     r = (((pixel&0x7C00)>>10)<<3);                     \
  111.     g = (((pixel&0x03E0)>>5)<<3);                     \
  112.     b = ((pixel&0x001F)<<3);                     \
  113. }
  114. #define RGB_FROM_RGB888(pixel, r, g, b)                    \
  115. {                                    \
  116.     r = ((pixel&0xFF0000)>>16);                     \
  117.     g = ((pixel&0xFF00)>>8);                     \
  118.     b = (pixel&0xFF);                         \
  119. }
  120. #define RETRIEVE_RGB_PIXEL(buf, bpp, pixel)                   \
  121. do {                                       \
  122.     switch (bpp) {                               \
  123.         case 2:                               \
  124.             pixel = *((Uint16 *)(buf));               \
  125.         break;                               \
  126.                                        \
  127.         case 3: {                           \
  128.                 Uint8 *B = (Uint8 *)(buf);               \
  129.             if(SDL_BYTEORDER == SDL_LIL_ENDIAN) {           \
  130.                     pixel = B[0] + (B[1] << 8) + (B[2] << 16); \
  131.             } else {                       \
  132.                     pixel = (B[0] << 16) + (B[1] << 8) + B[2]; \
  133.             }                           \
  134.         }                               \
  135.         break;                               \
  136.                                        \
  137.         case 4:                               \
  138.             pixel = *((Uint32 *)(buf));               \
  139.         break;                               \
  140.                                        \
  141.         default:                           \
  142.             pixel = 0; /* appease gcc */               \
  143.         break;                               \
  144.     }                                   \
  145. } while(0)
  146.  
  147. #define DISEMBLE_RGB(buf, bpp, fmt, pixel, r, g, b)               \
  148. do {                                       \
  149.     switch (bpp) {                               \
  150.         case 2:                               \
  151.             pixel = *((Uint16 *)(buf));               \
  152.         break;                               \
  153.                                        \
  154.         case 3: {                           \
  155.                 Uint8 *B = (Uint8 *)buf;               \
  156.             if(SDL_BYTEORDER == SDL_LIL_ENDIAN) {           \
  157.                     pixel = B[0] + (B[1] << 8) + (B[2] << 16); \
  158.             } else {                       \
  159.                     pixel = (B[0] << 16) + (B[1] << 8) + B[2]; \
  160.             }                           \
  161.         }                               \
  162.         break;                               \
  163.                                        \
  164.         case 4:                               \
  165.             pixel = *((Uint32 *)(buf));               \
  166.         break;                               \
  167.                                        \
  168.             default:                           \
  169.                 pixel = 0;    /* prevent gcc from complaining */ \
  170.         break;                               \
  171.     }                                   \
  172.     RGB_FROM_PIXEL(pixel, fmt, r, g, b);                   \
  173. } while(0)
  174.  
  175. /* Assemble R-G-B values into a specified pixel format and store them */
  176. #define PIXEL_FROM_RGB(pixel, fmt, r, g, b)                \
  177. {                                    \
  178.     pixel = ((r>>fmt->Rloss)<<fmt->Rshift)|                \
  179.         ((g>>fmt->Gloss)<<fmt->Gshift)|                \
  180.         ((b>>fmt->Bloss)<<fmt->Bshift);                \
  181. }
  182. #define RGB565_FROM_RGB(pixel, r, g, b)                    \
  183. {                                    \
  184.     pixel = ((r>>3)<<11)|((g>>2)<<5)|(b>>3);            \
  185. }
  186. #define RGB555_FROM_RGB(pixel, r, g, b)                    \
  187. {                                    \
  188.     pixel = ((r>>3)<<10)|((g>>3)<<5)|(b>>3);            \
  189. }
  190. #define RGB888_FROM_RGB(pixel, r, g, b)                    \
  191. {                                    \
  192.     pixel = (r<<16)|(g<<8)|b;                    \
  193. }
  194. #define ASSEMBLE_RGB(buf, bpp, fmt, r, g, b)                 \
  195. {                                    \
  196.     switch (bpp) {                            \
  197.         case 2: {                        \
  198.             Uint16 pixel;                    \
  199.                                     \
  200.             PIXEL_FROM_RGB(pixel, fmt, r, g, b);        \
  201.             *((Uint16 *)(buf)) = pixel;            \
  202.         }                            \
  203.         break;                            \
  204.                                     \
  205.         case 3: {                        \
  206.                         if(SDL_BYTEORDER == SDL_LIL_ENDIAN) {        \
  207.                     *((buf)+fmt->Rshift/8) = r;        \
  208.                 *((buf)+fmt->Gshift/8) = g;        \
  209.                 *((buf)+fmt->Bshift/8) = b;        \
  210.             } else {                    \
  211.                     *((buf)+2-fmt->Rshift/8) = r;        \
  212.                 *((buf)+2-fmt->Gshift/8) = g;        \
  213.                 *((buf)+2-fmt->Bshift/8) = b;        \
  214.             }                        \
  215.         }                            \
  216.         break;                            \
  217.                                     \
  218.         case 4: {                        \
  219.             Uint32 pixel;                    \
  220.                                     \
  221.             PIXEL_FROM_RGB(pixel, fmt, r, g, b);        \
  222.             *((Uint32 *)(buf)) = pixel;            \
  223.         }                            \
  224.         break;                            \
  225.     }                                \
  226. }
  227. #define ASSEMBLE_RGB_AMASK(buf, bpp, fmt, r, g, b, Amask)        \
  228. {                                    \
  229.     switch (bpp) {                            \
  230.         case 2: {                        \
  231.             Uint16 *bufp;                    \
  232.             Uint16 pixel;                    \
  233.                                     \
  234.             bufp = (Uint16 *)buf;                \
  235.             PIXEL_FROM_RGB(pixel, fmt, r, g, b);        \
  236.             *bufp = pixel | (*bufp & Amask);        \
  237.         }                            \
  238.         break;                            \
  239.                                     \
  240.         case 3: {                        \
  241.                         if(SDL_BYTEORDER == SDL_LIL_ENDIAN) {        \
  242.                     *((buf)+fmt->Rshift/8) = r;        \
  243.                 *((buf)+fmt->Gshift/8) = g;        \
  244.                 *((buf)+fmt->Bshift/8) = b;        \
  245.             } else {                    \
  246.                     *((buf)+2-fmt->Rshift/8) = r;        \
  247.                 *((buf)+2-fmt->Gshift/8) = g;        \
  248.                 *((buf)+2-fmt->Bshift/8) = b;        \
  249.             }                        \
  250.         }                            \
  251.         break;                            \
  252.                                     \
  253.         case 4: {                        \
  254.             Uint32 *bufp;                    \
  255.             Uint32 pixel;                    \
  256.                                     \
  257.             bufp = (Uint32 *)buf;                \
  258.             PIXEL_FROM_RGB(pixel, fmt, r, g, b);        \
  259.             *bufp = pixel | (*bufp & Amask);        \
  260.         }                            \
  261.         break;                            \
  262.     }                                \
  263. }
  264.  
  265. /* FIXME: Should we rescale alpha into 0..255 here? */
  266. #define RGBA_FROM_PIXEL(pixel, fmt, r, g, b, a)                \
  267. {                                    \
  268.     r = ((pixel&fmt->Rmask)>>fmt->Rshift)<<fmt->Rloss;         \
  269.     g = ((pixel&fmt->Gmask)>>fmt->Gshift)<<fmt->Gloss;         \
  270.     b = ((pixel&fmt->Bmask)>>fmt->Bshift)<<fmt->Bloss;         \
  271.     a = ((pixel&fmt->Amask)>>fmt->Ashift)<<fmt->Aloss;         \
  272. }
  273. #define RGBA_FROM_8888(pixel, fmt, r, g, b, a)    \
  274. {                        \
  275.     r = (pixel&fmt->Rmask)>>fmt->Rshift;    \
  276.     g = (pixel&fmt->Gmask)>>fmt->Gshift;    \
  277.     b = (pixel&fmt->Bmask)>>fmt->Bshift;    \
  278.     a = (pixel&fmt->Amask)>>fmt->Ashift;    \
  279. }
  280. #define RGBA_FROM_RGBA8888(pixel, r, g, b, a)                \
  281. {                                    \
  282.     r = (pixel>>24);                        \
  283.     g = ((pixel>>16)&0xFF);                        \
  284.     b = ((pixel>>8)&0xFF);                        \
  285.     a = (pixel&0xFF);                        \
  286. }
  287. #define RGBA_FROM_ARGB8888(pixel, r, g, b, a)                \
  288. {                                    \
  289.     r = ((pixel>>16)&0xFF);                        \
  290.     g = ((pixel>>8)&0xFF);                        \
  291.     b = (pixel&0xFF);                        \
  292.     a = (pixel>>24);                        \
  293. }
  294. #define RGBA_FROM_ABGR8888(pixel, r, g, b, a)                \
  295. {                                    \
  296.     r = (pixel&0xFF);                        \
  297.     g = ((pixel>>8)&0xFF);                        \
  298.     b = ((pixel>>16)&0xFF);                        \
  299.     a = (pixel>>24);                        \
  300. }
  301. #define DISEMBLE_RGBA(buf, bpp, fmt, pixel, r, g, b, a)               \
  302. do {                                       \
  303.     switch (bpp) {                               \
  304.         case 2:                               \
  305.             pixel = *((Uint16 *)(buf));               \
  306.         break;                               \
  307.                                        \
  308.         case 3:    {/* FIXME: broken code (no alpha) */           \
  309.                 Uint8 *b = (Uint8 *)buf;               \
  310.             if(SDL_BYTEORDER == SDL_LIL_ENDIAN) {           \
  311.                     pixel = b[0] + (b[1] << 8) + (b[2] << 16); \
  312.             } else {                       \
  313.                     pixel = (b[0] << 16) + (b[1] << 8) + b[2]; \
  314.             }                           \
  315.         }                               \
  316.         break;                               \
  317.                                        \
  318.         case 4:                               \
  319.             pixel = *((Uint32 *)(buf));               \
  320.         break;                               \
  321.                                        \
  322.         default:                           \
  323.                 pixel = 0; /* stop gcc complaints */           \
  324.         break;                               \
  325.     }                                   \
  326.     RGBA_FROM_PIXEL(pixel, fmt, r, g, b, a);               \
  327.     pixel &= ~fmt->Amask;                           \
  328. } while(0)
  329.  
  330. /* FIXME: this isn't correct, especially for Alpha (maximum != 255) */
  331. #define PIXEL_FROM_RGBA(pixel, fmt, r, g, b, a)                \
  332. {                                    \
  333.     pixel = ((r>>fmt->Rloss)<<fmt->Rshift)|                \
  334.         ((g>>fmt->Gloss)<<fmt->Gshift)|                \
  335.         ((b>>fmt->Bloss)<<fmt->Bshift)|                \
  336.         ((a<<fmt->Aloss)<<fmt->Ashift);                \
  337. }
  338. #define ASSEMBLE_RGBA(buf, bpp, fmt, r, g, b, a)            \
  339. {                                    \
  340.     switch (bpp) {                            \
  341.         case 2: {                        \
  342.             Uint16 pixel;                    \
  343.                                     \
  344.             PIXEL_FROM_RGBA(pixel, fmt, r, g, b, a);    \
  345.             *((Uint16 *)(buf)) = pixel;            \
  346.         }                            \
  347.         break;                            \
  348.                                     \
  349.         case 3: { /* FIXME: broken code (no alpha) */        \
  350.                         if(SDL_BYTEORDER == SDL_LIL_ENDIAN) {        \
  351.                     *((buf)+fmt->Rshift/8) = r;        \
  352.                 *((buf)+fmt->Gshift/8) = g;        \
  353.                 *((buf)+fmt->Bshift/8) = b;        \
  354.             } else {                    \
  355.                     *((buf)+2-fmt->Rshift/8) = r;        \
  356.                 *((buf)+2-fmt->Gshift/8) = g;        \
  357.                 *((buf)+2-fmt->Bshift/8) = b;        \
  358.             }                        \
  359.         }                            \
  360.         break;                            \
  361.                                     \
  362.         case 4: {                        \
  363.             Uint32 pixel;                    \
  364.                                     \
  365.             PIXEL_FROM_RGBA(pixel, fmt, r, g, b, a);    \
  366.             *((Uint32 *)(buf)) = pixel;            \
  367.         }                            \
  368.         break;                            \
  369.     }                                \
  370. }
  371.  
  372. /* Blend the RGB values of two pixels based on a source alpha value */
  373. #define ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB)    \
  374. do {                        \
  375.     dR = (((sR-dR)*(A))>>8)+dR;        \
  376.     dG = (((sG-dG)*(A))>>8)+dG;        \
  377.     dB = (((sB-dB)*(A))>>8)+dB;        \
  378. } while(0)
  379.  
  380. /* This is a very useful loop for optimizing blitters */
  381. #define USE_DUFFS_LOOP
  382. #ifdef USE_DUFFS_LOOP
  383.  
  384. /* 8-times unrolled loop */
  385. #define DUFFS_LOOP8(pixel_copy_increment, width)            \
  386. { int n = (width+7)/8;                            \
  387.     switch (width % 8) {                        \
  388.     case 0: do {    pixel_copy_increment;                \
  389.     case 7:        pixel_copy_increment;                \
  390.     case 6:        pixel_copy_increment;                \
  391.     case 5:        pixel_copy_increment;                \
  392.     case 4:        pixel_copy_increment;                \
  393.     case 3:        pixel_copy_increment;                \
  394.     case 2:        pixel_copy_increment;                \
  395.     case 1:        pixel_copy_increment;                \
  396.         } while ( --n > 0 );                    \
  397.     }                                \
  398. }
  399.  
  400. /* 4-times unrolled loop */
  401. #define DUFFS_LOOP4(pixel_copy_increment, width)            \
  402. { int n = (width+3)/4;                            \
  403.     switch (width % 4) {                        \
  404.     case 0: do {    pixel_copy_increment;                \
  405.     case 3:        pixel_copy_increment;                \
  406.     case 2:        pixel_copy_increment;                \
  407.     case 1:        pixel_copy_increment;                \
  408.         } while ( --n > 0 );                    \
  409.     }                                \
  410. }
  411.  
  412. /* Use the 8-times version of the loop by default */
  413. #define DUFFS_LOOP(pixel_copy_increment, width)                \
  414.     DUFFS_LOOP8(pixel_copy_increment, width)
  415.  
  416. #else
  417.  
  418. /* Don't use Duff's device to unroll loops */
  419. #define DUFFS_LOOP(pixel_copy_increment, width)                \
  420. { int n;                                \
  421.     for ( n=width; n > 0; --n ) {                    \
  422.         pixel_copy_increment;                    \
  423.     }                                \
  424. }
  425. #define DUFFS_LOOP8(pixel_copy_increment, width)            \
  426.     DUFFS_LOOP(pixel_copy_increment, width)
  427. #define DUFFS_LOOP4(pixel_copy_increment, width)            \
  428.     DUFFS_LOOP(pixel_copy_increment, width)
  429.  
  430. #endif /* USE_DUFFS_LOOP */
  431.  
  432. /* Prevent Visual C++ 6.0 from printing out stupid warnings */
  433. #if defined(_MSC_VER) && (_MSC_VER >= 600)
  434. #pragma warning(disable: 4550)
  435. #endif
  436.  
  437. #endif /* _SDL_blit_h */
  438.